package com.nuanshui.heatedloan.service.cms.security;

import java.util.ArrayList;
import java.util.List;

import org.hibernate.service.spi.ServiceException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.nuanshui.heatedloan.constant.TransactionManagerType;
import com.nuanshui.heatedloan.dao.cms.security.OrganizationDao;
import com.nuanshui.heatedloan.entity.cms.security.Organization;
import com.nuanshui.heatedloan.service.cms.BaseService;
import com.nuanshui.heatedloan.util.dwz.DwzPage;
import com.nuanshui.heatedloan.util.springdata.PageUtils;



/**
 * 部门的Service
 */
@Service
@Transactional(readOnly = true,value=TransactionManagerType.MANAGER_SERVICE_TRANSACTION_MARGER)
public class OrganizationService extends BaseService<Organization, Long> {

	@Autowired
	private OrganizationDao organizationDao;

	/**
	 * 删除模块
	 */
	@Override
	@Transactional(value=TransactionManagerType.MANAGER_SERVICE_TRANSACTION_MARGER)
	public void delete(final Long id) throws ServiceException {
		if (isRoot(id)) {
			throw new ServiceException("不允许删除根组织。");
		}

		final Organization organization = organizationDao.findOne(id);

		// 先判断是否存在子模块，如果存在子模块，则不允许删除
		if (organization.getChildren().size() > 0) {
			throw new ServiceException(organization.getName()
					+ "组织下存在子组织，不允许删除。");
		}

		organizationDao.delete(id);
	}

	/**
	 * 根据parentId分页
	 */
	public List<Organization> find(final Long parentId, final DwzPage page) {
		final org.springframework.data.domain.Page<Organization> p = organizationDao
				.findByParentId(parentId, PageUtils.createPageable(page));
		PageUtils.injectPageProperties(page, p);
		return p.getContent();
	}

	/**
	 * 根据组织名称查询
	 */
	public List<Organization> find(final Long parentId, final String name,
			final DwzPage page) {
		final org.springframework.data.domain.Page<Organization> p = organizationDao
				.findByParentIdAndNameContaining(parentId, name,
						PageUtils.createPageable(page));
		PageUtils.injectPageProperties(page, p);
		return p.getContent();
	}

	/**
	 * 判断是否是根组织.
	 */
	private boolean isRoot(final Long id) {
		return id == 1;
	}

	/**
	 * 得到根组织，注释参考module
	 */
	public Organization getTree() {
		final List<Organization> list = organizationDao.findAllWithCache();
		final List<Organization> rootList = makeTree(list);

		return rootList.get(0);
	}

	private List<Organization> makeTree(final List<Organization> list) {
		final List<Organization> parent = new ArrayList<Organization>();
		for (final Organization e : list) {
			if (e.getParent() == null) {
				e.setChildren(new ArrayList<Organization>(0));
				parent.add(e);
			}
		}
		list.removeAll(parent);

		makeChildren(parent, list);

		return parent;
	}

	private void makeChildren(final List<Organization> parent,
			final List<Organization> children) {
		if (children.isEmpty()) {
			return;
		}

		final List<Organization> tmp = new ArrayList<Organization>();
		for (final Organization c1 : parent) {
			for (final Organization c2 : children) {
				c2.setChildren(new ArrayList<Organization>(0));
				if (c1.getId().equals(c2.getParent().getId())) {
					c1.getChildren().add(c2);
					tmp.add(c2);
				}
			}
		}

		children.removeAll(tmp);

		makeChildren(tmp, children);
	}
}
